#ifndef TYPE_H
#define TYPE_H

#include "coretypes.h"

#include <typeinfo>

#include <QtCore/QHash>
#include <QtCore/QPair>
#include <QtCore/QSet>

namespace core
{

#define OP(ret) QPair<TypeName, TypeName>(ret, "")
#define OP2(ret,rOp) QPair<TypeName, TypeName>(ret, rOp)

class Type
{
public:
    Type();
    virtual ~Type() = 0;

    virtual QString name() const;
    virtual bool matches(const TypeName& name) const;
    virtual bool matches(const Type& type) const;
    virtual bool supports(const OperationName& name) const;
    virtual QSet<OperationName> supportedOperations() const;
    virtual TypeName operationReturnType(const OperationName& name) const;
    virtual TypeName rightOperatorType(const OperationName& name) const;
    virtual bool hasIdentity() const;
    virtual void setIdentity(const Type& identity);

    virtual bool canConvert(const TypeValue& value) const = 0;
    virtual ValueKeywordMask keywordMask() const = 0;

    virtual Type* copy() const = 0; 

    static TypeName demangledName(const char* name);

public:
    static const TypeValue INVALID_VALUE;
    static const TypeName INVALID_NAME;

protected:
    QHash<OperationName, QPair<TypeName, TypeName> > m_operations;
};

} // namespace core

#endif
